package com.example.capsule.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
/**
 * 文件存储服务
 */
@Service
public class FileStorageService {

    private final Path fileStorageLocation;

    public FileStorageService(@Value("${app.upload-dir}") String uploadDir) throws IOException {
        this.fileStorageLocation = Paths.get(uploadDir).toAbsolutePath().normalize();

        // 创建上传目录
        if (!Files.exists(this.fileStorageLocation)) {
            Files.createDirectories(this.fileStorageLocation);
        }
    }

    /**
     * 存储文件
     */
    public String storeFile(MultipartFile file) throws IOException {
        // 生成唯一文件名
        String originalFileName = file.getOriginalFilename();
        String fileExtension = "";

        if (originalFileName != null && originalFileName.contains(".")) {
            fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
        }

        String fileName = UUID.randomUUID() + fileExtension;

        // 检查文件名是否包含非法字符
        if (fileName.contains("..")) {
            throw new IOException("文件名包含非法路径序列: " + fileName);
        }

        // 复制文件到目标位置
        Path targetLocation = this.fileStorageLocation.resolve(fileName);
        Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

        return fileName;
    }

    /**
     * 删除文件
     */
    public void deleteFile(String fileName) throws IOException {
        Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
        Files.deleteIfExists(filePath);
    }

    /**
     * 加载文件作为资源
     */
    public Resource loadFileAsResource(String fileName) throws IOException {
        Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
        Resource resource = new UrlResource(filePath.toUri());

        if (resource.exists()) {
            return resource;
        } else {
            throw new IOException("文件未找到: " + fileName);
        }
    }

    /**
     * 检查文件是否存在
     */
    public boolean fileExists(String fileName) {
        Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
        return Files.exists(filePath);
    }

    /**
     * 获取文件大小
     */
    public long getFileSize(String fileName) throws IOException {
        Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
        return Files.size(filePath);
    }

    /**
     * 获取文件最后修改时间
     */
    public long getFileLastModified(String fileName) throws IOException {
        Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
        return Files.getLastModifiedTime(filePath).toMillis();
    }

    /**
     * 获取所有文件列表
     */
    public List<String> getAllFiles() throws IOException {
        return Files.list(fileStorageLocation)
                .filter(Files::isRegularFile)
                .map(Path::getFileName)
                .map(Path::toString)
                .collect(Collectors.toList());
    }

    /**
     * 获取文件存储路径
     */
    public Path getFileStorageLocation() {
        return fileStorageLocation;
    }

    /**
     * 清理临时文件（可选）
     */
    public void cleanupOldFiles(Duration maxAge) throws IOException {
        Instant cutoff = Instant.now().minus(maxAge);

        Files.list(fileStorageLocation)
                .filter(Files::isRegularFile)
                .filter(path -> {
                    try {
                        return Files.getLastModifiedTime(path).toInstant().isBefore(cutoff);
                    } catch (IOException e) {
                        return false;
                    }
                })
                .forEach(path -> {
                    try {
                        Files.delete(path);
                    } catch (IOException e) {
                        // 记录日志但继续处理其他文件
                        System.err.println("无法删除文件: " + path + ", 错误: " + e.getMessage());
                    }
                });
    }
}